package main

import (
	"sync"
	"sync/atomic"
)

type DBPool struct {
	Host     string
	Port     int
	UserName string
}

var dbPoolIns *DBPool
var lock sync.Mutex
var inittialed uint32

// GetDBPool 有问题的方法, 并发
// 加锁 功能上没有问题, 但是性能不好
// 高并发下, 有bug
//
// goroutine1 进来, 实例化 dbPoolIns = &DBPool{} 进行到一半, goroutine2 进来, dbPoolIns 读到 dbPoolIns != nil, 这时候, 返回 dbPoolIns
func GetDBPool() *DBPool {
	if atomic.LoadUint32(&inittialed) == 1 { // atomic 原子性读取操作
		return dbPoolIns
	}

	lock.Lock() // 这里上锁是怕高并发情况下 有多个 goroutine 同时进入
	defer lock.Unlock()

	if inittialed == 0 { // 这里再判断一次
		dbPoolIns = &DBPool{}
		atomic.StoreUint32(&inittialed, 1) // atomic 原子性写入操作
	}

	return dbPoolIns
}

var once sync.Once

func GetDBPool2() *DBPool {
	once.Do(func() {
		dbPoolIns = &DBPool{}
	})
	return dbPoolIns
}
